/**
 * 
 */
package me.myachievements.pagination;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import me.myachievements.pagination.control.Sort;
import me.myachievements.pagination.util.CriteriaModifications;

/**
 * @author besseym
 *
 */
public abstract class PaginationDao<T> extends HibernateDaoSupport {

	private String primaryKey;
	
	/**
	 * Constructor
	 * @param primaryKey
	 */
	public PaginationDao(String primaryKey){
		this.primaryKey = primaryKey;
	}
	
	/**
	 * Get Pagination Query
	 * @return
	 */
	protected abstract DetachedCriteria getCriteria(CriteriaModifications criteriaModifications);
	
	/**
	 * 
	 * @return
	 */
	public Integer getCount(CriteriaModifications criteriaDetails){
		DetachedCriteria criteria = getCriteria(criteriaDetails).setProjection(Projections.countDistinct(primaryKey));
		return (Integer) this.getHibernateTemplate().findByCriteria(criteria).get(0);
	}
	
	/**
	 * 
	 * @param firstResult
	 * @param maxResults
	 * @param sort
	 * @return
	 */
	public List<T> getPage(Integer firstResult, Integer maxResults, CriteriaModifications criteriaModifications){
		
		DetachedCriteria criteria = getCriteria(criteriaModifications);
		
		if(criteriaModifications != null){
			Sort sort = criteriaModifications.getSort();
			if(sort != null){
				if(sort.getAscending()){
					criteria.addOrder(Order.asc(sort.getProperty()).ignoreCase());
				}
				else{
					criteria.addOrder(Order.desc(sort.getProperty()).ignoreCase());
				}
			}
		}
		
		return this.getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults);
	}

}
